package com.adds.lvds.security.acegi;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.adds.lvds.core.utils.Md5Tool;
import com.adds.lvds.security.acegi.utils.Common;
import com.adds.lvds.security.dao.SysUserLogMapper;
import com.adds.lvds.security.dao.SysUserMapper;
import com.adds.lvds.security.model.SysCurrentUser;
import com.adds.lvds.security.model.SysUserLog;

/**
 * 用户登录验证
 * 
 * @author zhangjian 2016-08-12
 * @Email: 
 * @version 1.0v
 */

public class MyAuthenticationFilter extends
		UsernamePasswordAuthenticationFilter {
	public static final String ACEGI_SECURITY_FORM_USERNAME_KEY = "j_username";
	public static final String ACEGI_SECURITY_FORM_PASSWORD_KEY = "j_password";
	public static final String ACEGI_SECURITY_LAST_USERNAME_KEY = "ACEGI_SECURITY_LAST_USERNAME";
	@Autowired
	 private SysUserMapper sysUserMapper;
	@Autowired
	private SysUserLogMapper sysUserLogMapper;

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request,
			HttpServletResponse response) throws AuthenticationException {
		// System.err.println(" ---------------  MyAuthenticationFilter attemptAuthentication--------------- ");

		if (!request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException(
					"Authentication method not supported: "
							+ request.getMethod());
		}

		String username = obtainUsername(request);
		if (null != username && !username.equals("")) {
			username = username.trim();
		}
		String password = obtainPassword(request);
		if (null != password && !password.equals("")) {
			password = password.trim();
		}
		String reg = "(?:')";
		Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
		if (sqlPattern.matcher(username).find()) {
			throw new AuthenticationServiceException("登信息不合法");
		}
		if (sqlPattern.matcher(password).find()) {
			throw new AuthenticationServiceException("登信息不合法");
		}

		username = Html2Text(username);
		password = Html2Text(password);
		if (Common.isEmpty(username) || Common.isEmpty(password)) {
			throw new AuthenticationServiceException("账号或密码不能为空！");// 在界面输出自定义的信息！！
		}

		// 验证用户账号与密码是否正确
		Map<String,Object> map=new HashMap<>();
		map.put("username", username);
		SysCurrentUser sysUser = this.sysUserMapper
				.getSysUserByMap(map);
		if ((sysUser != null && !sysUser.getUserName().equals(username))) {
			throw new UsernameNotFoundException("账户错误，请重新输入！");// 在界面输出自定义的信息！！
		}
		if ((sysUser != null && !sysUser.getPassword().equals(
				Md5Tool.getMd5(password)))) {
			throw new UsernameNotFoundException("密码错误，请重新输入！");// 在界面输出自定义的信息！！
		}
		// 当验证都通过后，把用户信息放在session里
		request.getSession().setAttribute(SysCurrentUser.LVDS_CURRENT_USER_OBJECT_KEY, sysUser);
		SysUserLog userLogin = new SysUserLog();
		if (sysUser != null) {
			userLogin.setUserId(sysUser.getId());
			userLogin.setUserName(sysUser.getUserName());
			userLogin.setLoginIP(this.getIpAddrByRequest(request));
			try {
				sysUserLogMapper.addSysUserLog(userLogin);
			} catch (Exception e) {
			}
		}
		// 实现 Authentication
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
				username, Md5Tool.getMd5(password));
		// 允许子类设置详细属性
		setDetails(request, authRequest);
		request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY,
				username);
		// 运行UserDetailsService的loadUserByUsername 再次封装Authentication
		return this.getAuthenticationManager().authenticate(authRequest);
	}

	protected void setDetails(HttpServletRequest request,
			UsernamePasswordAuthenticationToken authRequest) {
		super.setDetails(request, authRequest);
	}

	@Override
	protected String obtainUsername(HttpServletRequest request) {
		Object obj = request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY);
		return null == obj ? "" : obj.toString();
	}

	@Override
	protected String obtainPassword(HttpServletRequest request) {
		Object obj = request.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY);
		return null == obj ? "" : obj.toString();
	}

	public String getIpAddrByRequest(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	public static String Html2Text(String inputString) {
		String htmlStr = inputString; // 含html标签的字符串
		String textStr = "";
		java.util.regex.Pattern p_script;
		java.util.regex.Matcher m_script;
		java.util.regex.Pattern p_style;
		java.util.regex.Matcher m_style;
		java.util.regex.Pattern p_html;
		java.util.regex.Matcher m_html;

		java.util.regex.Pattern p_html1;
		java.util.regex.Matcher m_html1;

		try {
			String regEx_script = "<[//s]*?script[^>]*?>[//s//S]*?<[//s]*?///[//s]*?script[//s]*?>"; // 定义script的正则表达式{或<script[^>]*?>[//s//S]*?<///script>
			String regEx_style = "<[//s]*?style[^>]*?>[//s//S]*?<[//s]*?///[//s]*?style[//s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[//s//S]*?<///style>
			String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
			String regEx_html1 = "<[^>]+";
			p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
			m_script = p_script.matcher(htmlStr);
			htmlStr = m_script.replaceAll(""); // 过滤script标签

			p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
			m_style = p_style.matcher(htmlStr);
			htmlStr = m_style.replaceAll(""); // 过滤style标签

			p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
			m_html = p_html.matcher(htmlStr);
			htmlStr = m_html.replaceAll(""); // 过滤html标签

			p_html1 = Pattern.compile(regEx_html1, Pattern.CASE_INSENSITIVE);
			m_html1 = p_html1.matcher(htmlStr);
			htmlStr = m_html1.replaceAll(""); // 过滤html标签

			textStr = htmlStr;

		} catch (Exception e) {
			System.err.println("Html2Text: " + e.getMessage());
		}

		return textStr;// 返回文本字符串
	}

}
